package comunicacion.simulador;

import java.awt.Toolkit;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import javax.vecmath.Point3d;

import comunicacion.Conector;

import estrategia.ParametrosGlobales;

public class Simulador implements Conector {
	private int idRobot;
	private int motorIzquierdo;
	private int motorDerecho;
	
	private DatagramSocket simSocket;
	private InetAddress serverIP;
	private int serverPort;
	
	private Point3d[] ultimasCoordenadasObjetos;	
	Radar radar;
	
	
	public Simulador(String ipServidor, int puertoServidor, int idRobot, int idMotorIzquierdo, int idMotorDerecho) throws IOException {
		
		this.serverIP = InetAddress.getByName(ipServidor);
		this.serverPort = puertoServidor;
		
		this.idRobot = idRobot;
		this.motorIzquierdo = idMotorIzquierdo;
		this.motorDerecho = idMotorDerecho;
		
		this.simSocket = new DatagramSocket();

		// Enviamos la solicitud para la creacion del robot y el campo de juego
		String mensajeCreacion = LectorArchivo.leer("CreacionAgenteEntorno.xml");
		int puertoLocal = simSocket.getLocalPort();
		mensajeCreacion = mensajeCreacion.replaceAll("#puertoLocal#", String.valueOf(puertoLocal));
		mensajeCreacion = mensajeCreacion.replaceAll("#idRobot#", String.valueOf(idRobot));
		mensajeCreacion = mensajeCreacion.replaceAll("#motorIzquierdo#", String.valueOf(motorIzquierdo));
		mensajeCreacion = mensajeCreacion.replaceAll("#motorDerecho#", String.valueOf(motorDerecho));
		DatagramPacket paquete = new DatagramPacket(mensajeCreacion.getBytes(), mensajeCreacion.length(), serverIP, serverPort);
		simSocket.send(paquete);
		
		moverEntidad(idRobot);
		
		// Indicamos el inicio de la simulacion
		String mensajeInicio = LectorArchivo.leer("IniciarSimulacion.xml");
		paquete = new DatagramPacket(mensajeInicio.getBytes(), mensajeInicio.length(), serverIP, serverPort);
		simSocket.send(paquete);
		
		radar = new Radar(this);
		radar.start();
		
		ultimasCoordenadasObjetos = new Point3d[ParametrosGlobales.CANTIDAD_OBJETOS];
		for (int i=0; i<ultimasCoordenadasObjetos.length; i++)
			ultimasCoordenadasObjetos[i] = new Point3d(0, 0, 0);
	}
	
	private void moverEntidad(int idEntidad) throws IOException {
		String texto = LectorArchivo.leer("ReubicarEntidad.xml");
		
		texto = texto.replaceAll("#idRobot#", String.valueOf(idEntidad));
		texto = texto.replaceAll("#pos_x#", String.valueOf(0.8));
		texto = texto.replaceAll("#pos_y#", String.valueOf(0.6 + idEntidad*0.2));
		
		DatagramPacket paquete = new DatagramPacket(texto.getBytes(), texto.length(), serverIP, serverPort);
		simSocket.send(paquete);
	}
	
	public DatagramSocket getSocket() {
		return simSocket;
	}
	
	public void setUltimasCoordenadas(int idObjeto, Point3d coordenadas) {
		ultimasCoordenadasObjetos[idObjeto].x = coordenadas.x;
		ultimasCoordenadasObjetos[idObjeto].y = coordenadas.y;
		ultimasCoordenadasObjetos[idObjeto].z = coordenadas.z;
	}
	
	@Override
	public void detenerMotores() throws IOException {
		this.enviarVelocidades(0.0, 0.0);		
	}
	
	@Override
	public void enviarVelocidades(double velocidadIzquierda, double velocidadDerecha) throws IOException {
		String velocidades = LectorArchivo.leer("Velocidades.xml");
		
		velocidades = velocidades.replaceAll("#idRobot#", String.valueOf(idRobot));
		velocidades = velocidades.replaceAll("#motorIzquierdo#", String.valueOf(motorIzquierdo));
		velocidades = velocidades.replaceAll("#velocidadIzquierda#", String.valueOf(velocidadIzquierda));
		velocidades = velocidades.replaceAll("#motorDerecho#", String.valueOf(motorDerecho));
		velocidades = velocidades.replaceAll("#velocidadDerecha#", String.valueOf(velocidadDerecha));
		
		DatagramPacket paquete = new DatagramPacket(velocidades.getBytes(), velocidades.length(), serverIP, serverPort);
		simSocket.send(paquete);
	}	

	@Override
	public Point3d getCoordenadas() throws IOException {
		return getCoordenadas(idRobot);
	}
	
	@Override
	public Point3d getCoordenadas(int idEntidad) throws IOException {
		Point3d unaCoord = new Point3d();
		unaCoord.x = ultimasCoordenadasObjetos[idEntidad].x;
		unaCoord.y = ultimasCoordenadasObjetos[idEntidad].y;
		unaCoord.z = ultimasCoordenadasObjetos[idEntidad].z;
		
		return unaCoord;
	}
	
	@Override
	public Point3d[] getCoordenadasObjetos() throws IOException {		
		Point3d[] coordenadas = new Point3d[ultimasCoordenadasObjetos.length-1];
		for (int i=0; i<ultimasCoordenadasObjetos.length; i++) {
			Point3d unaCoord = new Point3d();
			unaCoord.x = ultimasCoordenadasObjetos[i].x;
			unaCoord.y = ultimasCoordenadasObjetos[i].y;
			unaCoord.z = ultimasCoordenadasObjetos[i].z;
			
			if (i < idRobot) 
				coordenadas[i] = unaCoord;
			else if (i > idRobot)
				coordenadas[i-1] = unaCoord;
		}
		
		return coordenadas;
	}
	
	private void registrarObstaculo(int idEntidad, double masa, double posX, double posY, double rot, double tamX, double tamY, double tamZ) throws IOException {
		String obstaculo = LectorArchivo.leer("CreacionObstaculo.xml");
		
		obstaculo = obstaculo.replaceAll("#idEntidad#", String.valueOf(idEntidad));
		obstaculo = obstaculo.replaceAll("#masa#", String.valueOf(masa));
		double posZ = 0.06 + tamZ/2.0;
		obstaculo = obstaculo.replaceAll("#posX#", String.valueOf(posX));
		obstaculo = obstaculo.replaceAll("#posY#", String.valueOf(posY));
		obstaculo = obstaculo.replaceAll("#posZ#", String.valueOf(posZ));
		
		obstaculo = obstaculo.replaceAll("#rotacion#", String.valueOf(rot));
		
		obstaculo = obstaculo.replaceAll("#sizeX#", String.valueOf(tamX));
		obstaculo = obstaculo.replaceAll("#sizeY#", String.valueOf(tamY));
		obstaculo = obstaculo.replaceAll("#sizeZ#", String.valueOf(tamZ));
		
		DatagramPacket paquete = new DatagramPacket(obstaculo.getBytes(), obstaculo.length(), serverIP, serverPort);
		simSocket.send(paquete);
	}

	@Override
	public void enviarBeep() {
		// No hacemos nada	
		Toolkit.getDefaultToolkit().beep();
	}
	
	@Override
	public void guardarSimulacion(String path, String archivo) throws IOException {
		// Enviamos la solicitud para guardar el estado de la simulacion
		String mensaje = "<Message>" +
							"<Simulation_Message>" +
								"<Control_Request Command = \"Save\">" +
									"<File>" +
										path + archivo + //"/home/current_user/simulation.xml" +
									"</File>" +
								"</Control_Request>" +
							"</Simulation_Message>" +
						 "</Message>";
		//int puertoLocal = simSocket.getLocalPort();
		DatagramPacket paquete = new DatagramPacket(mensaje.getBytes(), mensaje.length(), serverIP, serverPort);
		simSocket.send(paquete);
	}
	
	@Override
	public void cargarSimulacion(String path, String archivo) throws IOException {
		// Enviamos la solicitud para guardar el estado de la simulacion
		String mensaje = "<Message>" +
									"<Simulation_Message>" +
										"<Control_Request Command = \"Load\">" +
											"<File>" +
												path + archivo + //"/home/current_user/simulation.xml" +
											"</File>" +
										"</Control_Request>" +
									"</Simulation_Message>" +
								"</Message>";
		//int puertoLocal = simSocket.getLocalPort();
		DatagramPacket paquete = new DatagramPacket(mensaje.getBytes(), mensaje.length(), serverIP, serverPort);
		simSocket.send(paquete);
	}

}
